home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue46 / packages / DinoSource.Zip / WindowMenu.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1998-10-29  |  7.7 KB  |  267 lines

  1. unit WindowMenu;
  2.  
  3. {$ifdef Ver100} { Delphi 3.0x }
  4.   {$define DelphiLessThan4}
  5. {$endif}
  6. {$ifdef Ver110} { C++ Builder 3.0x }
  7.   {$define DelphiLessThan4}
  8. {$endif}
  9.  
  10. interface
  11.  
  12. procedure Register;
  13.  
  14. implementation
  15.  
  16. uses
  17.   ExptIntf, ToolIntf, Windows, Messages, CommonStuff, Menus, Forms, SysUtils,
  18.   Dialogs, ExtCtrls;
  19.  
  20. type
  21.   TWindowMenu = class(TIExpert)
  22.   private
  23.     FWindowMenu: TIMenuItemIntf;
  24.     FWindowMenuOption: TMenuItem;
  25.   protected
  26.     procedure DoAbout(Sender: TIMenuItemIntf);
  27.     procedure DoWindowMenu(Sender: TObject);
  28.     procedure DoWindowMenuClick(Sender: TIMenuItemIntf);
  29.     procedure DoWindowItemClick(Sender: TIMenuItemIntf);
  30.     procedure SetWindowMenu(Value: Boolean);
  31.   public
  32.     constructor Create;
  33.     destructor Destroy; override;
  34.     function GetName:        string; override;
  35.     function GetComment:     string; override;
  36.     function GetAuthor:      string; override;
  37.     function GetPage:        string; override;
  38.     function GetGlyph:       HICON;  override;
  39.     function GetStyle: TExpertStyle; override;
  40.     function GetState: TExpertState; override;
  41.     function GetIDString:    string; override;
  42.     function GetMenuText:    string; override;
  43.     procedure Execute;               override;
  44.   end;
  45.  
  46. resourcestring
  47.   SWindow = 'W&indow';             //Default Window menu caption
  48.   SInspector = 'Object Inspector'; //Object Inspector window caption
  49.   SWindowMenu = '&Window menu';    //Window menu toggle option
  50.  
  51. const
  52.   SFormat = '&%d %s';      //Format for Window menu item
  53.   SIconCaptionClass = '#32772'; //Class name of an NT 3.5 icon caption
  54.   //Registry strings
  55.   SRegWindowMenu = 'Window Menu';
  56.   SRegWindowMenuName = 'Window Menu Caption';
  57.  
  58. constructor TWindowMenu.Create;
  59. begin
  60.   inherited;
  61.   //Make sure there is an options menu - bear in mind
  62.   //that the other options code might not be being used
  63.   Stuff.AddOptionsItem;
  64.   //Set up Window menu options menu item
  65.   FWindowMenuOption := NewItem(SWindowMenu, 0,
  66.     Stuff.Ini.ReadBool(SRegSection, SRegWindowMenu, False),
  67.     True, DoWindowMenu, 0, '');
  68.   //Insert the menu item
  69.   Stuff.FOptions.Add(FWindowMenuOption);
  70.   //Set the window menu as appropriate
  71.   SetWindowMenu(FWindowMenuOption.Checked);
  72. end;
  73.  
  74. destructor TWindowMenu.Destroy;
  75. begin
  76.   //Save Window menu existence state
  77.   Stuff.Ini.WriteBool(SRegSection,
  78.     SRegWindowMenu, FWindowMenuOption.Checked);
  79.   //Delete Window menu
  80.   SetWindowMenu(False);
  81.   inherited Destroy
  82. end;
  83.  
  84. procedure TWindowMenu.DoAbout(Sender: TIMenuItemIntf);
  85. begin
  86.   Stuff.DoAbout(nil)
  87. end;
  88.  
  89. procedure TWindowMenu.DoWindowMenu(Sender: TObject);
  90. begin
  91.   //When user toggles Window menu option, set
  92.   //checkmark and set Window menu accordingly
  93.   with Sender as TMenuItem do
  94.   begin
  95.     Checked := not Checked;
  96.     SetWindowMenu(Checked)
  97.   end
  98. end;
  99.  
  100. procedure TWindowMenu.DoWindowMenuClick(Sender: TIMenuItemIntf);
  101. var
  102.   Loop, Count, OldCount: Integer;
  103.   PID: {$ifdef DelphiLessThan4}Integer{$else}Cardinal{$endif};
  104.   Item: TIMenuItemIntf;
  105.   Wnd: HWnd;
  106.   WndClass, WndCaption: array[0..255] of Char;
  107. begin
  108.   //Delphi repetitively calls the OnClick events of the
  109.   //main menu items to allow IDE code to en/disable
  110.   //speedbuttons as necessary. We will only execute
  111.   //this code if it is a real menu click (Sender =
  112.   //the menu item) - not a fake one from Delphi (where
  113.   //Sender = the main window)
  114.   if Sender = FWindowMenu then
  115.   begin
  116.     Count := 0;
  117.     //It would normally be sensible to delete the old items
  118.     //and then add new items. But for some reason that goes
  119.     //screwy UI-wise, so instead we add the new ones and
  120.     //then delete the old ones
  121.     //So, how many Window menu items were there?
  122.     OldCount := FWindowMenu.GetItemCount;
  123.     //Add new menu items for current windows
  124.     Wnd := GetWindow(Application.Handle, gw_HWndFirst);
  125.     while Wnd <> 0 do
  126.     begin
  127.       GetClassName(Wnd, WndClass, 255);
  128.       GetWindowThreadProcessID(Wnd, @PID);
  129.       //We only want windows in the Window menu
  130.       //that are... visible, enabled, have a caption,
  131.       //are not icon captions, are part of the Delphi
  132.       //process and are not the Application window
  133.       if IsWindowVisible(Wnd) and
  134.          IsWindowEnabled(Wnd) and
  135.          (GetWindowText(Wnd, WndCaption, 255) > 0) and
  136.          (PID = GetCurrentProcessID) and
  137.          (StrPas(WndClass) <> SIconCaptionClass) and
  138.          (StrPas(WndClass) <> Application.ClassName) then
  139.       begin
  140.         Inc(Count);
  141.         //Make a new menu item, remembering to put the
  142.         //checkmark on the currently selected page
  143.         //Menu item stores reference to the relevant form in Hint
  144.         Item := FWindowMenu.InsertItem(FWindowMenu.GetItemCount,
  145.           Format(SFormat, [Count, StrPas(WndCaption)]), '',
  146.           IntToStr(Wnd), 0, 0, 57, [mfEnabled, mfVisible, mfRadioItem],
  147.           DoWindowItemClick);
  148.         //Put F11 next to Object Inspector item as a reminder
  149.         if StrPas(WndCaption) = SInspector then
  150.           Item.SetShortCut(vk_F11); //Don't use TextToShortCut!!
  151.       end;
  152.       Wnd := GetWindow(Wnd, gw_HWndNext)
  153.     end;
  154.     //Add About menu item
  155.     FWindowMenu.InsertItem(FWindowMenu.GetItemCount, '-', '', '',
  156.       0, 0, 0, [mfEnabled, mfVisible], nil);
  157.     FWindowMenu.InsertItem(FWindowMenu.GetItemCount, SAbout, '',
  158.       '', 0, 0, 0, [mfEnabled, mfVisible], DoAbout);
  159.     //Now delete the old (potentially wrong) window menu items
  160.     for Loop := 1 to OldCount do
  161.       FWindowMenu.GetItem(0).DestroyMenuItem;
  162.   end
  163. end;
  164.  
  165. procedure TWindowMenu.DoWindowItemClick(Sender: TIMenuItemIntf);
  166. begin
  167.   //Restore selected window (in case it was minimised)
  168.   PostMessage(StrToInt(Sender.GetHint), wm_SysCommand, sc_Restore, 0);
  169.   //Make selected window active
  170.   SetForegroundWindow(StrToInt(Sender.GetHint))
  171. end;
  172.  
  173. procedure TWindowMenu.SetWindowMenu(Value: Boolean);
  174. var
  175.   FMainmenu: TIMainMenuIntf;
  176. begin
  177.   if Value then
  178.   begin
  179.     if Assigned(ToolServices) then
  180.     begin
  181.       FMainMenu := ToolServices.GetMainMenu;
  182.       if Assigned(FMainMenu) then
  183.         try
  184.           FWindowMenu := FMainMenu.GetMenuItems.InsertItem(
  185.             FMainMenu.GetMenuItems.GetItemCount-1,
  186.             Stuff.Ini.ReadString(SRegSection, SRegWindowMenuName, SWindow),
  187.             '', '', 0, 0, 0, [mfEnabled, mfVisible], DoWindowMenuClick)
  188.         finally
  189.           FMainMenu.Free
  190.         end
  191.     end
  192.   end
  193.   else
  194.   begin
  195.     //This deletes the Window menu
  196.     if Assigned(FWindowMenu) then
  197.     begin
  198.       FWindowMenu.DestroyMenuItem;
  199.       FWindowMenu := nil
  200.     end
  201.   end;
  202. {$ifndef DelphiLessThan4}
  203.   //Resize menu bar to take account of added/deleted menu item
  204.   if Assigned(Stuff.FControlBar) then
  205.   begin
  206.     Stuff.FControlBar.Perform(wm_LButtonDown, 0, MakeLong(0, 0));
  207.     Stuff.FControlBar.Perform(wm_LButtonUp, 0, MakeLong(0, 0));
  208.   end
  209. {$endif}
  210. end;
  211.  
  212. function TWindowMenu.GetName: string;
  213. begin
  214.   Result := 'Archaeopteryx''s Window Menu';
  215. end;
  216.  
  217. function TWindowMenu.GetComment: string;
  218. begin
  219.   Result := '';
  220. end ;
  221.  
  222. function TWindowMenu.GetAuthor: string;
  223. begin
  224.   Result := '';
  225. end ;
  226.  
  227. function TWindowMenu.GetPage: string;
  228. begin
  229.   Result := '';
  230. end;
  231.  
  232. function TWindowMenu.GetGlyph: HICON;
  233. begin
  234.   Result := 0;
  235. end;
  236.  
  237. function TWindowMenu.GetStyle: TExpertStyle;
  238. begin
  239.   Result := esAddIn;
  240. end;
  241.  
  242. function TWindowMenu.GetState: TExpertState;
  243. begin
  244.   Result := [esEnabled];
  245. end;
  246.  
  247. function TWindowMenu.GetIDString: string;
  248. begin
  249.   Result := 'Archaeopteryx.WindowMenu';
  250. end;
  251.  
  252. function TWindowMenu.GetMenuText: string;
  253. begin
  254.   Result := '';
  255. end ;
  256.  
  257. procedure TWindowMenu.Execute;
  258. begin
  259. end;
  260.  
  261. procedure Register;
  262. begin
  263.   RegisterLibraryExpert(TWindowMenu.Create)
  264. end;
  265.  
  266. end.
  267.